package com.bitcointoolkit.common.cash;

/**
 * [类描述]
 *
 * @author caican
 * @date 18/6/17
 */
public class EncodeUtil {

    public static byte[] toBytes(String str) {
        if(str == null || "".equals(str.trim())) {
            return new byte[0];
        }

        byte[] bytes = new byte[str.length() / 2];
        for(int i = 0; i < str.length() / 2; i++) {
            String subStr = str.substring(i * 2, i * 2 + 2);
            bytes[i] = (byte) Integer.parseInt(subStr, 16);
        }

        return bytes;
    }

    public static int[] toInts(String str) {
        byte[] bytes = toBytes(str);
        return bytesToInts(bytes);
    }

    public static int[] bytesToInts(byte[] bytes) {
        int[] ints = new int[bytes.length];
        for(int i = 0; i < bytes.length; i++) {
            ints[i] = bytes[i] & 0xff;
        }
        return ints;
    }
    /**
     * @param in
     * @return int
     */
    public static int parseInt16(int[] in) {
        if (in.length!=2) {
            throw new IllegalArgumentException("parseInt32 must have array len = 4");
        }
        for (int each:in){
            if (each>255) {
                throw new IllegalArgumentException("input must < 256, 一个字符是8位");
            }
        }
        int ret = in[0] | in[1] << 8;
        return ret;
    }

    /**
     * @param in
     * @return 由于是无符号32位整形，所有返回的是long
     */
    public static long parseInt32(int[] in) {
        if (in.length!=4) {
            throw new IllegalArgumentException("parseInt32 must have array len = 4");
        }
        for (int each:in){
            if (each>255) {
                throw new IllegalArgumentException("input must < 256, 一个字符是8位");
            }
        }
        long ret = in[0] | in[1] << 8 | in[2] << 16 | (long)in[3] << 24;
        return ret;
    }

    /**
     * @param in 输入
     * @return 目前只支持 有符号long
     */
    public static long parseInt64(int[] in) {
        if (in.length!=8) {
            throw new IllegalArgumentException("parseInt64 must have array len = 8");
        }
        for (int each:in){
            if (each>255) {
                throw new IllegalArgumentException("input must < 256, 一个字符是8位");
            }
        }
        long ret = in[0] | in[1] << 8 | in[2] << 16 | (long)in[3] << 24 |
             (long)in[4] << 32 | (long)in[5] << 40 |(long)in[6] << 48 |(long)in[7]<<56;
        if (ret < 0) {
            throw new RuntimeException("long overflow!");
        }
        return ret;
    }

    /** int数组拆解
     * @param ints 输入
     * @param fromIndex 开始
     * @param toIndex 结束
     * @return 新数组
     */
    public static int[] subInt(int[] ints, int fromIndex, int toIndex){
        int[] ret = new int[toIndex-fromIndex];
        if (fromIndex < 0 || toIndex > ints.length || fromIndex > toIndex) {
            throw new IllegalArgumentException();
        }
        for (int i=fromIndex,j=0; i<toIndex; i++,j++) {
            ret[j] = ints[i];
        }
        return ret;
    }

    /**
     * 输入 {0x01,0x02,0x03} 的数组
     * 输出 "030201"
     */
    public static String parseBigEndianToString(int[] input) {
        StringBuffer sb = new StringBuffer();
        for(int i= input.length-1; i>=0; i--){
            int b = input[i];
            String hexString = Integer.toHexString(b);
            if (hexString.length() ==1) {
                sb.append('0');
            }
            sb.append(hexString);
        }
        return sb.toString();
    }
    /**
     * 输入 {0x01,0x02,0x03} 的数组
     * 输出 "030201"
     */
    public static String parseBigEndianToString(byte[] input) {
        return parseBigEndianToString(bytesToInts(input));
    }

    /**
     * 输入 {0x0a,0x0b,0x0c} 的数组
     * 输出 "0a0b0c"
     */
    public static String parseToString(int[] input) {
        StringBuffer sb = new StringBuffer();
        for(int i= 0; i<input.length; i++){
            int b = input[i];
            String hexString = Integer.toHexString(b);
            if (hexString.length() ==1) {
                sb.append('0');
            }
            sb.append(hexString);
        }
        return sb.toString();
    }

    /**
     * 输入 {0x0a,0x0b,0x0c} 的数组
     * 输出 "0a0b0c"
     */
    public static String parseToString(byte[] input) {
        return parseToString(bytesToInts(input));
    }

    /**
     * byte 数组合并
     */
    public static byte[] byteMerger(byte[] bt1, byte[] bt2){
        byte[] bt3 = new byte[bt1.length+bt2.length];
        System.arraycopy(bt1, 0, bt3, 0, bt1.length);
        System.arraycopy(bt2, 0, bt3, bt1.length, bt2.length);
        return bt3;
    }

    /**
     * Returns a copy of the given byte array in reverse order.
     */
    public static byte[] reverseBytes(byte[] bytes) {
        // We could use the XOR trick here but it's easier to understand if we don't. If we find this is really a
        // performance issue the matter can be revisited.
        byte[] buf = new byte[bytes.length];
        for (int i = 0; i < bytes.length; i++)
            buf[i] = bytes[bytes.length - 1 - i];
        return buf;
    }
}